﻿using System;
using System.Diagnostics.Contracts;
using System.Net.Http;
using System.Threading.Tasks;
using Wx.Sdk.Api.Entity;
using Wx.Sdk.Ext;
using Wx.Sdk.Utils;

namespace Wx.Sdk.Api.Base
{
    internal class ApiBase
    {
        WxApi wxApi;
        internal ApiBase(WxApi wxApi)
        {
            this.wxApi = wxApi;
        }
        /// <summary>
        /// 获取微信的AccessToken
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<string> GetAccessToken()
        {
            var key = $"WeChatApplicationWithAccessToken_{wxApi.apiOption.appid}";
            //获取缓存中的值
            var tokenCache = wxApi.wxCache.Get<string>(key);
            if (tokenCache.IsNull())
            {
                var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={wxApi.apiOption.appid}&secret={wxApi.apiOption.appsecret}";
                var str = await Get(url);
                var accessToken = JsonHelper.ToModel<AccessToken>(str);
                Contract.Assume(accessToken != null);
                tokenCache = accessToken.access_token;
                //存入缓存,绝对过期时间
                wxApi.wxCache.Set(key, tokenCache, accessToken.expires_in - 100);
            }
            return tokenCache;
        }
        /// <summary>
        /// 获取微信的JsApiTicket
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<string> getJsApi_Ticket()
        {
            var key = $"WeChatApplicationWithJsApiTicket_{wxApi.apiOption.appid}";
            var ticketCache = wxApi.wxCache.Get<string>(key);
            if (ticketCache.IsNull())
            {
                var access_token = await GetAccessToken();
                var url = $"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={access_token}&type=jsapi";
                //远程拉取字符串
                var str = await Get(url);
                JsApiTicket ticket = JsonHelper.ToModel<JsApiTicket>(str);
                ticketCache = ticket.ticket;
                wxApi.wxCache.Set(key, ticketCache, ticket.expires_in - 100);
            }
            return ticketCache;
        }
        /// <summary>
        /// GET数据
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public async Task<string> Get(string url)
        {
            Contract.Assume(!url.IsNull());
            var client = wxApi.httpClientFactory.CreateClient();
            //远程拉取字符串
            var data = await client.GetStringAsync(url);
            var err = JsonHelper.ToModel<WxMsg>(data);
            return err.errcode == 0 ? data : throw new WxError($"GET错误:{data}");
        }
        /// <summary>
        /// POST数据
        /// </summary>
        /// <param name="body"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public async Task<string> Post(string body, string url)
        {
            Contract.Assume(!url.IsNull());
            var client = wxApi.httpClientFactory.CreateClient();
            var content = new StringContent(body);
            var responseMsg = await client.PostAsync(url, content);
            var data = await responseMsg.Content.ReadAsStringAsync();
            var err = JsonHelper.ToModel<WxMsg>(data);
            return err.errcode == 0 ? data : throw new WxError($"POST错误:{data}");
        }
    }
}
